import NetData from "../NetData";
import LengthOptimizeConfig from "./LengthOptimizeConfig";

export default class ProtoDecoder {
    private len: LengthOptimizeConfig;
    private proto: protobuf.Root;
    constructor(len, proto) {
        this.len = len;
        this.proto = proto;
    }
    /**
     * 响应消息格式
     *   cmdIndex(4)
     * + serviceAndMethodLength(1)
     * + serviceAndMethod(serviceAndmethodLength)
     * + protoNameLength(1)
     * + protoName(protoNameLength)
     * + protobuf数据(最后所有长度)
     */
    decode(byteArray: ArrayBuffer) {
        if (byteArray.byteLength < 8) {
            console.log("数据长度不足8字节");
            throw new Error("数据长度不足8字节");
        }
        const dataView = new DataView(byteArray);
        const cmdIndex = dataView.getInt32(0);
        const serviceAndMethodLength = dataView.getInt8(4);
        let serviceAndMethod = String.fromCharCode.apply(null, new Uint8Array(byteArray.slice(5, 5 + serviceAndMethodLength)));
        const replaceServiceAndMethodName = this.len.decoderServiceNameMap[serviceAndMethod];
        if (replaceServiceAndMethodName) {
            serviceAndMethod = replaceServiceAndMethodName;
        }
        const protoNameLength = dataView.getUint8(5 + serviceAndMethodLength);
        let protoName = String.fromCharCode.apply(null, new Uint8Array(byteArray.slice(5 + serviceAndMethodLength + 1, 5 + serviceAndMethodLength + 1 + protoNameLength)));
        const replaceProtoName = this.len.decoderProtoNameMap[protoName];
        if (replaceProtoName) {
            protoName = replaceProtoName;
        }
        const cls = NetData.pbRoot.lookupType("proto." + protoName);
        const msg = byteArray.slice(5 + serviceAndMethodLength + 1 + protoNameLength, byteArray.byteLength);
        try {
            const uint8Array = new Uint8Array(msg);
            const dataProto = cls.decode(uint8Array);
            return { dataProto, serviceAndMethod, protoName, cmdIndex };
        } catch (e) {
            console.log("解码失败：", protoName + ",", serviceAndMethod,e);
        }
    }
}